package com.billy.ohos.loadingstatusview.wrapability.adapter.view.anim;

import ohos.agp.animation.Animator;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Arc;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.Point;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by lumingmin on 16/6/24.
 */

public class LVFinePoiStar extends LVBase implements Component.DrawTask {

    private float mWidth = 0f;
    private float mPadding;
    private Paint mPaintLine, mPaintCircle;
    private int hornCount = 5;
    float mAnimatedValue = 0.75f;
    private List<StarPoint> listPoint = new ArrayList<StarPoint>();
    private boolean isDrawPath = true;
    RectFloat rectF = new RectFloat();

    public LVFinePoiStar(Context context) {
        this(context, null);
    }

    public LVFinePoiStar(Context context, AttrSet attrSet) {
        this(context, attrSet, null);
    }

    public LVFinePoiStar(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        mPadding = dip2px(1);
    }

    @Override
    protected void InitPaint() {
        mPaintLine = new Paint();
        mPaintLine.setAntiAlias(true);
        mPaintLine.setStyle(Paint.Style.FILL_STYLE);
        mPaintLine.setColor(Color.WHITE);
        mPaintLine.setStrokeWidth(dip2px(1f));

        mPaintCircle = new Paint();
        mPaintCircle.setAntiAlias(true);
        mPaintCircle.setStyle(Paint.Style.STROKE_STYLE);
        mPaintCircle.setColor(Color.WHITE);
        mPaintCircle.setStrokeWidth(dip2px(1));
        addDrawTask(this);
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        if (getWidth() > getHeight()) {
            mWidth = getHeight();
        } else {
            mWidth = getWidth();
        }
        listPoint.clear();
        for (int i = 0; i < hornCount; i++) {
            StarPoint starPoint = getPoint(mWidth / 2 - mPadding, (90 - 360 / hornCount) + 360 / hornCount * i);
            listPoint.add(starPoint);
        }
        StarPoint cp;
        float currenttime = (mAnimatedValue * 10 - (int) (mAnimatedValue * 10));
        if (mAnimatedValue >= 0 && mAnimatedValue <= 0.1f) {
            cp = drawOneEdge(currenttime, 1f, listPoint.get(0), listPoint.get(2));
            if (isDrawPath) {
                drawPathEdge(canvas, listPoint.get(0), cp);
            } else {
                canvas.drawCircle(mWidth / 2 - cp.x, mWidth / 2 - cp.y, mPadding, mPaintLine);
            }
        } else if (mAnimatedValue > 0.1f && mAnimatedValue <= 0.2f) {
            cp = drawOneEdge(currenttime, 1f, listPoint.get(2), listPoint.get(4));
            if (isDrawPath) {
                drawEdge(canvas, 1);
                drawPathEdge(canvas, listPoint.get(2), cp);
            } else {
                canvas.drawCircle(mWidth / 2 - cp.x, mWidth / 2 - cp.y, mPadding, mPaintLine);
            }
        } else if (mAnimatedValue > 0.2f && mAnimatedValue <= 0.3f) {
            cp = drawOneEdge(currenttime, 1f, listPoint.get(4), listPoint.get(1));
            if (isDrawPath) {
                drawEdge(canvas, 2);
                drawPathEdge(canvas, listPoint.get(4), cp);
            } else {
                canvas.drawCircle(mWidth / 2 - cp.x, mWidth / 2 - cp.y, mPadding, mPaintLine);
            }
        } else if (mAnimatedValue > 0.3f && mAnimatedValue <= 0.4f) {
            cp = drawOneEdge(currenttime, 1f, listPoint.get(1), listPoint.get(3));
            if (isDrawPath) {
                drawEdge(canvas, 3);
                drawPathEdge(canvas, listPoint.get(1), cp);
            } else {
                canvas.drawCircle(mWidth / 2 - cp.x, mWidth / 2 - cp.y, mPadding, mPaintLine);
            }
        } else if (mAnimatedValue > 0.4f && mAnimatedValue <= 0.5f) {
            cp = drawOneEdge(currenttime, 1f, listPoint.get(3), listPoint.get(0));
            if (isDrawPath) {
                drawEdge(canvas, 4);
                drawPathEdge(canvas, listPoint.get(3), cp);
            } else {
                canvas.drawCircle(mWidth / 2 - cp.x, mWidth / 2 - cp.y, mPadding, mPaintLine);
            }
        } else if (mAnimatedValue > 0.5f && mAnimatedValue <= 0.75f) {
            drawEdge(canvas, 5);
            rectF = new RectFloat(mPadding, mPadding, mWidth - mPadding, mWidth - mPadding);
            canvas.drawArc(rectF, new Arc(-180 + ((90 - 360 / hornCount)), 360 / 0.25f * (mAnimatedValue - 0.5f), false), mPaintCircle);
        } else {
            mPaintCircle.setStrokeWidth(dip2px(1.5f));
            drawEdge(canvas, 5);
            rectF = new RectFloat(mPadding, mPadding, mWidth - mPadding, mWidth - mPadding);
            canvas.drawArc(rectF, new Arc(-180 + ((90 - 360 / hornCount)), 360, false), mPaintCircle);
        }
        mPaintCircle.setStrokeWidth(dip2px(1.0f));
    }

    private StarPoint drawOneEdge(float currenttime, float alltime, StarPoint startP, StarPoint endP) {
        float x = startP.x - (startP.x - endP.x) / alltime * currenttime;
        float y = startP.y - (startP.y - endP.y) / alltime * currenttime;
        StarPoint resPoint = new StarPoint(x, y);
        return resPoint;
    }

    private void drawFirstEdge(Canvas canvas) {
        canvas.drawLine(new Point(mWidth / 2 - listPoint.get(0).x, mWidth / 2 - listPoint.get(0).y),
                new Point(mWidth / 2 - listPoint.get(2).x, mWidth / 2 - listPoint.get(2).y), mPaintLine);
    }

    private void drawSecondEdge(Canvas canvas) {
        canvas.drawLine(new Point(mWidth / 2 - listPoint.get(2).x, mWidth / 2 - listPoint.get(2).y),
                new Point(mWidth / 2 - listPoint.get(4).x, mWidth / 2 - listPoint.get(4).y), mPaintLine);
    }

    private void drawThirdEdge(Canvas canvas) {
        canvas.drawLine(new Point(mWidth / 2 - listPoint.get(4).x, mWidth / 2 - listPoint.get(4).y),
                new Point(mWidth / 2 - listPoint.get(1).x, mWidth / 2 - listPoint.get(1).y), mPaintLine);
    }

    private void drawFourthEdge(Canvas canvas) {
        canvas.drawLine(new Point(mWidth / 2 - listPoint.get(1).x, mWidth / 2 - listPoint.get(1).y),
                new Point(mWidth / 2 - listPoint.get(3).x, mWidth / 2 - listPoint.get(3).y), mPaintLine);
    }

    private void drawFifthEdge(Canvas canvas) {
        canvas.drawLine(new Point(mWidth / 2 - listPoint.get(3).x, mWidth / 2 - listPoint.get(3).y),
                new Point(mWidth / 2 - listPoint.get(0).x, mWidth / 2 - listPoint.get(0).y), mPaintLine);
    }

    private void drawPathEdge(Canvas canvas, StarPoint start, StarPoint end) {
        canvas.drawLine(new Point(mWidth / 2 - start.x, mWidth / 2 - start.y),
                new Point(mWidth / 2 - end.x, mWidth / 2 - end.y), mPaintLine);
    }

    private void drawEdge(Canvas canvas, int edgeCount) {
        switch (edgeCount) {
            case 1:
                drawFirstEdge(canvas);
                break;
            case 2:
                drawFirstEdge(canvas);
                drawSecondEdge(canvas);
                break;
            case 3:
                drawFirstEdge(canvas);
                drawSecondEdge(canvas);
                drawThirdEdge(canvas);
                break;
            case 4:
                drawFirstEdge(canvas);
                drawSecondEdge(canvas);
                drawThirdEdge(canvas);
                drawFourthEdge(canvas);
                break;
            case 5:
                drawFirstEdge(canvas);
                drawSecondEdge(canvas);
                drawThirdEdge(canvas);
                drawFourthEdge(canvas);
                drawFifthEdge(canvas);
                break;
        }
    }

    public void setViewColor(int color) {
        mPaintLine.setColor(new Color(color));
        invalidate();
    }

    public void setCircleColor(int color) {
        mPaintCircle.setColor(new Color(color));
        invalidate();
    }

    public void setDrawPath(boolean isDrawPath) {
        this.isDrawPath = isDrawPath;
    }

    private StarPoint getPoint(float radius, float angle) {
        float x = (float) ((radius) * Math.cos(angle * Math.PI / 180f));
        float y = (float) ((radius) * Math.sin(angle * Math.PI / 180f));
        StarPoint p = new StarPoint(x, y);
        return p;
    }

    private class StarPoint {
        private float x;
        private float y;

        private StarPoint(float x, float y) {
            this.x = x;
            this.y = y;
        }
    }

    @Override
    protected void OnAnimationRepeat(Animator animation) {

    }

    @Override
    protected void OnAnimationUpdate(float value) {
        mAnimatedValue = value;
        invalidate();
    }

    @Override
    protected int OnStopAnim() {
        mAnimatedValue = 0.75f;
        invalidate();
        return 1;
    }

    @Override
    protected int SetAnimRepeatMode() {
        return RESTART;
    }

    @Override
    protected void AinmIsRunning() {

    }

    @Override
    protected int SetAnimRepeatCount() {
        return Integer.MAX_VALUE;
    }

}
